<!DOCTYPE html>



  


<html class="theme-next pisces use-motion" lang="">
<head>
  <meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
<meta name="theme-color" content="#222">









<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />
















  
  
  <link href="/blog/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css" />







<link href="/blog/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css" />

<link href="/blog/css/main.css?v=5.1.4" rel="stylesheet" type="text/css" />


  <link rel="apple-touch-icon" sizes="180x180" href="/blog/images/apple-touch-icon-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="32x32" href="/blog/images/favicon-32x32-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="16x16" href="/blog/images/favicon-16x16-next.png?v=5.1.4">


  <link rel="mask-icon" href="/blog/images/logo.svg?v=5.1.4" color="#222">





  <meta name="keywords" content="Hexo, NexT" />










<meta name="description" content="####1. ZooKeeper官方 ######1). 简介ZooKeeper是一个分布式的，开放源码的分布式应用程序协调服务，是Google的Chubby一个开源的实现，是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件，提供的功能包括：配置维护、域名服务、分布式同步、组服务等。ZooKeeper的目标就是封装好复杂易出错的关键服务，将简单易用的接口和性能高效、功能">
<meta name="keywords" content="Android、iOS、Web、React Native">
<meta property="og:type" content="article">
<meta property="og:title" content="分布式--ZooKeeper-分布式服务协同">
<meta property="og:url" content="http://yoursite.com/blog/2018/08/06/Distributed/分布式--ZooKeeper-分布式服务协同/index.html">
<meta property="og:site_name" content="凌浩雨_博客">
<meta property="og:description" content="####1. ZooKeeper官方 ######1). 简介ZooKeeper是一个分布式的，开放源码的分布式应用程序协调服务，是Google的Chubby一个开源的实现，是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件，提供的功能包括：配置维护、域名服务、分布式同步、组服务等。ZooKeeper的目标就是封装好复杂易出错的关键服务，将简单易用的接口和性能高效、功能">
<meta property="og:locale" content="default">
<meta property="og:image" content="https://upload-images.jianshu.io/upload_images/3110861-2195d504d912f55f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240">
<meta property="og:image" content="https://upload-images.jianshu.io/upload_images/3110861-3fe4cfd5e92c8341.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240">
<meta property="og:image" content="https://upload-images.jianshu.io/upload_images/3110861-c6736407104199da.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240">
<meta property="og:image" content="https://upload-images.jianshu.io/upload_images/3110861-a03079d6ffa8a8f8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240">
<meta property="og:image" content="https://upload-images.jianshu.io/upload_images/3110861-f64c273a88c51046.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240">
<meta property="og:image" content="https://upload-images.jianshu.io/upload_images/3110861-247024fa029fc755.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240">
<meta property="og:image" content="https://upload-images.jianshu.io/upload_images/3110861-3b8768aa617e312b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240">
<meta property="og:image" content="https://upload-images.jianshu.io/upload_images/3110861-ea341ebe6d6e5ce8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240">
<meta property="og:image" content="https://upload-images.jianshu.io/upload_images/3110861-f2240ec1a444d03e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240">
<meta property="og:image" content="https://upload-images.jianshu.io/upload_images/3110861-ff600e250feda4b2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240">
<meta property="og:image" content="https://upload-images.jianshu.io/upload_images/3110861-f6e053b245f9ac4d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240">
<meta property="og:image" content="https://upload-images.jianshu.io/upload_images/3110861-974abd030f644240.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240">
<meta property="og:image" content="https://upload-images.jianshu.io/upload_images/3110861-5bb90ff4d65b8f5e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240">
<meta property="og:image" content="https://upload-images.jianshu.io/upload_images/3110861-3252dde7be4ea27d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240">
<meta property="og:image" content="https://upload-images.jianshu.io/upload_images/3110861-d4d3d1124c15214a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240">
<meta property="og:image" content="https://upload-images.jianshu.io/upload_images/3110861-7e5f30375b57a7f0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240">
<meta property="og:image" content="https://upload-images.jianshu.io/upload_images/3110861-1fc478e32ca8db9f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240">
<meta property="og:updated_time" content="2018-08-06T11:07:44.755Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="分布式--ZooKeeper-分布式服务协同">
<meta name="twitter:description" content="####1. ZooKeeper官方 ######1). 简介ZooKeeper是一个分布式的，开放源码的分布式应用程序协调服务，是Google的Chubby一个开源的实现，是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件，提供的功能包括：配置维护、域名服务、分布式同步、组服务等。ZooKeeper的目标就是封装好复杂易出错的关键服务，将简单易用的接口和性能高效、功能">
<meta name="twitter:image" content="https://upload-images.jianshu.io/upload_images/3110861-2195d504d912f55f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240">



<script type="text/javascript" id="hexo.configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/blog/',
    scheme: 'Pisces',
    version: '5.1.4',
    sidebar: {"position":"left","display":"post","offset":12,"b2t":false,"scrollpercent":false,"onmobile":false},
    fancybox: true,
    tabs: true,
    motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
    duoshuo: {
      userId: '0',
      author: 'Author'
    },
    algolia: {
      applicationID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    }
  };
</script>



  <link rel="canonical" href="http://yoursite.com/blog/2018/08/06/Distributed/分布式--ZooKeeper-分布式服务协同/"/>





  <title>分布式--ZooKeeper-分布式服务协同 | 凌浩雨_博客</title>
  








</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="default">

  
  
    
  

  <div class="container sidebar-position-left page-post-detail">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-wrapper">
  <div class="site-meta ">
    

    <div class="custom-logo-site-title">
      <a href="/blog/"  class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">凌浩雨_博客</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
      
        <p class="site-subtitle"></p>
      
  </div>

  <div class="site-nav-toggle">
    <button>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
    </button>
  </div>
</div>

<nav class="site-nav">
  

  
    <ul id="menu" class="menu">
      
        
        <li class="menu-item menu-item-home">
          <a href="/blog/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-home"></i> <br />
            
            Home
          </a>
        </li>
      
        
        <li class="menu-item menu-item-archives">
          <a href="/blog/archives/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-archive"></i> <br />
            
            Archives
          </a>
        </li>
      

      
    </ul>
  

  
</nav>



 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">
            

  <div id="posts" class="posts-expand">
    

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/blog/blog/2018/08/06/Distributed/分布式--ZooKeeper-分布式服务协同/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="凌浩雨">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/blog/images/avatar.jpeg">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="凌浩雨_博客">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">分布式--ZooKeeper-分布式服务协同</h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">Posted on</span>
              
              <time title="Post created" itemprop="dateCreated datePublished" datetime="2018-08-06T18:01:38+08:00">
                2018-08-06
              </time>
            

            

            
          </span>

          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        <p>####1. <a href="http://zookeeper.apache.org/" target="_blank" rel="noopener">ZooKeeper官方</a></p>
<p>######1). 简介<br>ZooKeeper是一个分布式的，开放源码的分布式应用程序协调服务，是Google的Chubby一个开源的实现，是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件，提供的功能包括：配置维护、域名服务、分布式同步、组服务等。<br>ZooKeeper的目标就是封装好复杂易出错的关键服务，将简单易用的接口和性能高效、功能稳定的系统提供给用户。ZooKeeper包含一个简单的原语集，提供Java和C的接口。<br>ZooKeeper代码版本中，提供了分布式独享锁、选举、队列的接口，代码在zookeeper-3.4.8\src\recipes。其中分布锁和队列有Java和C两个版本，选举只有Java版本。</p>
<a id="more"></a>
<p>######2). <a href="http://49.119.164.213:6510/mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.4.10/zookeeper-3.4.10.tar.gz" target="_blank" rel="noopener">ZooKeeper下载</a><br><img src="https://upload-images.jianshu.io/upload_images/3110861-2195d504d912f55f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="图1.png"></p>
<p>######3). 分布式应用<br><img src="https://upload-images.jianshu.io/upload_images/3110861-3fe4cfd5e92c8341.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="图2.png"></p>
<p>######4). 优点及挑战</p>
<ul>
<li><p>分布式应用的优点</p>
<ul>
<li>可靠性 - 单个或几个系统的故障不会使整个系统出现故障。</li>
<li>可扩展性 - 可以在需要时增加性能，通过添加更多机器，在应用程序配置中进行微小的更改，而不会有停机时间。</li>
<li>透明性 - 隐藏系统的复杂性，并将其显示为单个实体/应用程序。</li>
</ul>
</li>
<li><p>分布式应用的挑战</p>
<ul>
<li>竞争条件 - 两个或多个机器尝试执行特定任务，实际上只需在任意给定时间由单个机器完成。例如，共享资源只能在任意给定时间由单个机器修改。</li>
<li>死锁 - 两个或多个操作等待彼此无限期完成。</li>
<li>不一致 - 数据的部分失败。<br>######5). ZooKeeper描述<br>Apache ZooKeeper是由集群（节点组）使用的一种服务，用于在自身之间协调，并通过稳健的同步技术维护共享数据。ZooKeeper本身是一个分布式应用程序，为写入分布式应用程序提供服务。<br>ZooKeeper提供的常见服务如下 :</li>
</ul>
</li>
<li>命名服务 - 按名称标识集群中的节点。它类似于DNS，但仅对于节点。</li>
<li>配置管理 - 加入节点的最近的和最新的系统配置信息。</li>
<li>集群管理 - 实时地在集群和节点状态中加入/离开节点。</li>
<li>选举算法 - 选举一个节点作为协调目的的leader。</li>
<li>锁定和同步服务 - 在修改数据的同时锁定数据。此机制可帮助你在连接其他分布式应用程序（如Apache HBase）时进行自动故障恢复。</li>
<li>高度可靠的数据注册表 - 即使在一个或几个节点关闭时也可以获得数据。<br>######6). 工作流<br>一旦ZooKeeper集合启动，它将等待客户端连接。客户端将连接到ZooKeeper集合中的一个节点。它可以是leader或follower节点。一旦客户端被连接，节点将向特定客户端分配会话ID并向该客户端发送确认。如果客户端没有收到确认，它将尝试连接ZooKeeper集合中的另一个节点。 一旦连接到节点，客户端将以有规律的间隔向节点发送心跳，以确保连接不会丢失。</li>
<li>如果客户端想要读取特定的znode，它将会向具有znode路径的节点发送读取请求，并且节点通过从其自己的数据库获取来返回所请求的znode。为此，在ZooKeeper集合中读取速度很快。</li>
<li>如果客户端想要将数据存储在ZooKeeper集合中，则会将znode路径和数据发送到服务器。连接的服务器将该请求转发给leader，然后leader将向所有的follower重新发出写入请求。如果只有大部分节点成功响应，而写入请求成功，则成功返回代码将被发送到客户端。 否则，写入请求失败。绝大多数节点被称为 Quorum 。<br>######7). 节点<br>让我们分析在ZooKeeper集合中拥有不同数量的节点的效果。</li>
<li>如果我们有单个节点，则当该节点故障时，ZooKeeper集合将故障。它有助于“单点故障”，不建议在生产环境中使用。</li>
<li>如果我们有两个节点而一个节点故障，我们没有占多数，因为两个中的一个不是多数。</li>
<li>如果我们有三个节点而一个节点故障，那么我们有大多数，因此，这是最低要求。ZooKeeper集合在实际生产环境中必须至少有三个节点。</li>
<li>如果我们有四个节点而两个节点故障，它将再次故障。类似于有三个节点，额外节点不用于任何目的，因此，最好添加奇数的节点，例如3，5，7。<br><img src="https://upload-images.jianshu.io/upload_images/3110861-c6736407104199da.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="图3.png"></li>
</ul>
<table>
<thead>
<tr>
<th>组件</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>写入（write）</td>
<td>写入过程由leader节点处理。leader将写入请求转发到所有znode，并等待znode的回复。如果一半的znode回复，则写入过程完成。</td>
<td></td>
</tr>
<tr>
<td>读取（read）</td>
<td>读取由特定连接的znode在内部执行，因此不需要与集群进行交互。</td>
<td></td>
</tr>
<tr>
<td>复制数据库（replicated database）</td>
<td>它用于在zookeeper中存储数据。每个znode都有自己的数据库，每个znode在一致性的帮助下每次都有相同的数据。</td>
<td></td>
</tr>
<tr>
<td>Leader</td>
<td>Leader是负责处理写入请求的Znode。</td>
<td></td>
</tr>
<tr>
<td>Follower</td>
<td>follower从客户端接收写入请求，并将它们转发到leader znode。</td>
<td></td>
</tr>
<tr>
<td>请求处理器（request processor）</td>
<td>只存在于leader节点。它管理来自follower节点的写入请求。</td>
<td></td>
</tr>
<tr>
<td>原子广播（atomic broadcasts）</td>
<td>负责广播从leader节点到follower节点的变化。</td>
<td></td>
</tr>
</tbody>
</table>
<p>####2. 安装</p>
<p>######1). 修改/conf/zoo_sample.cfg配置文件<br>I. 修改文件名zoo_sample.cfg为zoo.cfg.<br>  <img src="https://upload-images.jianshu.io/upload_images/3110861-a03079d6ffa8a8f8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="图4.png"></p>
<p>II. 修改zoo.cfg文件内容<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"># The number of milliseconds of each tick</span><br><span class="line">tickTime=2000</span><br><span class="line"># The number of ticks that the initial </span><br><span class="line"># synchronization phase can take</span><br><span class="line">initLimit=10</span><br><span class="line"># The number of ticks that can pass between </span><br><span class="line"># sending a request and getting an acknowledgement</span><br><span class="line">syncLimit=5</span><br><span class="line"># the directory where the snapshot is stored.</span><br><span class="line"># do not use /tmp for storage, /tmp here is just </span><br><span class="line"># example sakes.</span><br><span class="line">dataDir=D:\\zookeeper-3.4.10.tar\\zookeeper-3.4.10\\data</span><br><span class="line">dataLogDir=D:\\zookeeper-3.4.10.tar\\zookeeper-3.4.10\\log</span><br><span class="line"># the port at which the clients will connect</span><br><span class="line">clientPort=2181</span><br><span class="line"># the maximum number of client connections.</span><br><span class="line"># increase this if you need to handle more clients</span><br><span class="line">#maxClientCnxns=60</span><br><span class="line">#</span><br><span class="line"># Be sure to read the maintenance section of the </span><br><span class="line"># administrator guide before turning on autopurge.</span><br><span class="line">#</span><br><span class="line"># http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance</span><br><span class="line">#</span><br><span class="line"># The number of snapshots to retain in dataDir</span><br><span class="line">#autopurge.snapRetainCount=3</span><br><span class="line"># Purge task interval in hours</span><br><span class="line"># Set to &quot;0&quot; to disable auto purge feature</span><br><span class="line">#autopurge.purgeInterval=1</span><br></pre></td></tr></table></figure></p>
<p>III. 配置文件解析</p>
<ul>
<li>tickTime：这个时间是作为 Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔，也就是每个 tickTime 时间就会发送一个心跳。</li>
<li>dataDir：顾名思义就是 Zookeeper 保存数据的目录，默认情况下，Zookeeper 将写数据的日志文件也保存在这个目录里。</li>
<li>dataLogDir：顾名思义就是 Zookeeper 保存日志文件的目录</li>
<li>clientPort：这个端口就是客户端连接 Zookeeper 服务器的端口，Zookeeper 会监听这个端口，接受客户端的访问请求。<br>######2). 启动</li>
<li>进入到bin目录，并且启动zkServer.cmd，这时会启动一个java进程<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">zkServer.cmd</span><br></pre></td></tr></table></figure>
</li>
</ul>
<p><img src="https://upload-images.jianshu.io/upload_images/3110861-f64c273a88c51046.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="图5.png"></p>
<ul>
<li>查看进程<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">jps -l -v</span><br></pre></td></tr></table></figure>
</li>
</ul>
<p><img src="https://upload-images.jianshu.io/upload_images/3110861-247024fa029fc755.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="图6.png"></p>
<ul>
<li>客户端连接<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">zkCli.cmd 127.0.0.1:2181</span><br></pre></td></tr></table></figure>
</li>
</ul>
<p><img src="https://upload-images.jianshu.io/upload_images/3110861-3b8768aa617e312b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="图7.png"></p>
<p>####3. API代码测试</p>
<p>######1). 基础知识<br>与ZooKeeper集合进行交互的应用程序称为 ZooKeeper客户端或简称客户端。<br>Znode是ZooKeeper集合的核心组件，ZooKeeper API提供了一小组方法使用ZooKeeper集合来操纵znode的所有细节。<br>客户端应该遵循以步骤，与ZooKeeper集合进行清晰和干净的交互。</p>
<ul>
<li>连接到ZooKeeper集合。ZooKeeper集合为客户端分配会话ID。</li>
<li>定期向服务器发送心跳。否则，ZooKeeper集合将过期会话ID，客户端需要重新连接。</li>
<li>只要会话ID处于活动状态，就可以获取/设置znode。</li>
<li>所有任务完成后，断开与ZooKeeper集合的连接。如果客户端长时间不活动，则ZooKeeper集合将自动断开客户端。<br>######2). API<br>ZooKeeper API的核心部分是ZooKeeper类。它提供了在其构造函数中连接ZooKeeper集合的选项，并具有以下方法：</li>
<li>connect - 连接到ZooKeeper集合</li>
<li>create- 创建znode</li>
<li>exists- 检查znode是否存在及其信息</li>
<li>getData - 从特定的znode获取数据</li>
<li>setData - 在特定的znode中设置数据</li>
<li>getChildren - 获取特定znode中的所有子节点</li>
<li>delete - 删除特定的znode及其所有子项</li>
<li>close - 关闭连接</li>
</ul>
<p>新建Java工程，并导入/lib/log4j-1.2.16.jar、/lib/slf4j-api-1.6.1.jar、/lib/slf4j-log4j12-1.6.1.jar、zookeeper-3.4.10.jar，将/conf/路径下的log4j.properties文件拷贝到项目的src目录下<br><img src="https://upload-images.jianshu.io/upload_images/3110861-ea341ebe6d6e5ce8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="图8.png"></p>
<p>######3). connect(连接到ZooKeeper集合)<br>I. 方法原型<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ZooKeeper(String connectionString, int sessionTimeout, Watcher watcher)</span><br></pre></td></tr></table></figure></p>
<ul>
<li>connectionString - ZooKeeper集合主机。</li>
<li>sessionTimeout - 会话超时（以毫秒为单位）。</li>
<li>watcher - 实现“监视器”界面的对象。ZooKeeper集合通过监视器对象返回连接状态。<br>II. 代码<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line"> * ZooKeeper连接管理</span><br><span class="line"> * @author mazaiting</span><br><span class="line"> */</span><br><span class="line">public class ZooKeeperConnection &#123;</span><br><span class="line"></span><br><span class="line">	/**</span><br><span class="line">	 * 定义ZooKeeper实例</span><br><span class="line">	 */</span><br><span class="line">	private ZooKeeper zooKeeper;</span><br><span class="line">	/**</span><br><span class="line">	 * 用户停止(等待)主线程，直到客户端与ZooKeeper集合连接</span><br><span class="line">	 */</span><br><span class="line">	private final CountDownLatch connectedSignal = new CountDownLatch(1);</span><br><span class="line">	</span><br><span class="line">	/**</span><br><span class="line">	 * 连接</span><br><span class="line">	 * @param host 主机地址</span><br><span class="line">	 * @return ZooKeeper对象</span><br><span class="line">	 * @throws IOException IO异常</span><br><span class="line">	 * @throws InterruptedException 中断异常</span><br><span class="line">	 */</span><br><span class="line">	public ZooKeeper connect(String host) throws IOException, InterruptedException &#123;</span><br><span class="line">		// 创建ZooKeeper对象</span><br><span class="line">		zooKeeper = new ZooKeeper(host, 5000, new Watcher()&#123;</span><br><span class="line">			/**</span><br><span class="line">			 * </span><br><span class="line">			 */</span><br><span class="line">			@Override</span><br><span class="line">			public void process(WatchedEvent event) &#123;</span><br><span class="line">				if (event.getState() == KeeperState.SyncConnected) &#123;</span><br><span class="line">					connectedSignal.countDown();</span><br><span class="line">				&#125;</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;);</span><br><span class="line">		// 等待</span><br><span class="line">		connectedSignal.await();</span><br><span class="line">		return zooKeeper;</span><br><span class="line">	&#125;</span><br><span class="line">	</span><br><span class="line">	/**</span><br><span class="line">	 * 关机ZooKeeper的连接</span><br><span class="line">	 * @throws InterruptedException 中断异常</span><br><span class="line">	 */</span><br><span class="line">	public void close() throws InterruptedException &#123;</span><br><span class="line">		zooKeeper.close();</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>######4). create(创建znode)<br>I. 方法原型<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">create(String path, byte[] data, List&lt;ACL&gt; acl, CreateMode createMode)</span><br></pre></td></tr></table></figure></p>
<ul>
<li>path - Znode路径。例如，/myapp1，/myapp2，/myapp1/mydata1，myapp2/mydata1/myanothersubdata</li>
<li>data - 要存储在指定znode路径中的数据</li>
<li>acl - 要创建的节点的访问控制列表。ZooKeeper API提供了一个静态接口 ZooDefs.Ids 来获取一些基本的acl列表。例如，ZooDefs.Ids.OPEN_ACL_UNSAFE返回打开znode的acl列表。</li>
<li>createMode - 节点的类型，即临时，顺序或两者。这是一个枚举。</li>
</ul>
<p>II. 代码<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line"> * 创建节点</span><br><span class="line"> * @author mazaiting</span><br><span class="line"> */</span><br><span class="line">public class ZKCreate &#123;</span><br><span class="line">	/**</span><br><span class="line">	 * 创建静态的ZooKeeper实例</span><br><span class="line">	 */</span><br><span class="line">	private static ZooKeeper zooKeeper;</span><br><span class="line">	/**</span><br><span class="line">	 * 创建静态的连接实例</span><br><span class="line">	 */</span><br><span class="line">	private static ZooKeeperConnection conn;</span><br><span class="line">	</span><br><span class="line">	/**</span><br><span class="line">	 * 创建节点</span><br><span class="line">	 * @param path Znode路径</span><br><span class="line">	 * @param data 存储在Znode路径中的数据</span><br><span class="line">	 * @throws KeeperException ZooKeeper异常</span><br><span class="line">	 * @throws InterruptedException 中断异常</span><br><span class="line">	 */</span><br><span class="line">	public static void create(String path, byte[] data) throws KeeperException, InterruptedException &#123;</span><br><span class="line">		zooKeeper.create(path, data, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);</span><br><span class="line">	&#125;</span><br><span class="line">	</span><br><span class="line">	public static void main(String[] args) &#123;</span><br><span class="line">		// znode路径</span><br><span class="line">		String path = &quot;/MyFirst&quot;;</span><br><span class="line">		// 二进制数据</span><br><span class="line">		byte[] data = &quot;My First ZooKeeper app&quot;.getBytes();</span><br><span class="line">		</span><br><span class="line">		try &#123;</span><br><span class="line">			// 创建连接对象</span><br><span class="line">			conn = new ZooKeeperConnection();</span><br><span class="line">			// 连接， 并返回ZooKeeper</span><br><span class="line">			zooKeeper = conn.connect(&quot;127.0.0.1&quot;);</span><br><span class="line">			// 创建Znode</span><br><span class="line">			create(path, data);</span><br><span class="line">			// 关闭</span><br><span class="line">			conn.close();</span><br><span class="line">		&#125; catch (Exception e) &#123;</span><br><span class="line">			System.out.println(e.getMessage());</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">	</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>III. 测试</p>
<ul>
<li>执行结果：<br><img src="https://upload-images.jianshu.io/upload_images/3110861-f2240ec1a444d03e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="图9.png"></li>
<li>获取数据：在命令提示符中使用<code>zkCli.cmd</code>开启一个客户端窗口，<br><img src="https://upload-images.jianshu.io/upload_images/3110861-ff600e250feda4b2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="图10.png"><br>连接成功后, 输入<code>get /MyFirst</code>(get 路径名)查看数据<br><img src="https://upload-images.jianshu.io/upload_images/3110861-f6e053b245f9ac4d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="图10.png"></li>
</ul>
<p>######5). exists(检查znode是否存在及其信息)<br>I. 方法原型<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">exists(String path, boolean watcher)</span><br></pre></td></tr></table></figure></p>
<ul>
<li>path- Znode路径</li>
<li>watcher - 布尔值，用于指定是否监视指定的znode<br>II. 代码<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line"> * 判断某个路径是否存在</span><br><span class="line"> * @author mazaiting</span><br><span class="line"> */</span><br><span class="line">public class ZKExists &#123;</span><br><span class="line">	/**</span><br><span class="line">	 * 定义静态的ZooKeeper对象</span><br><span class="line">	 */</span><br><span class="line">	private static ZooKeeper zooKeeper;</span><br><span class="line">	/**</span><br><span class="line">	 * 定义静态的ZooKeeper连接对象</span><br><span class="line">	 */</span><br><span class="line">	private static ZooKeeperConnection conn;</span><br><span class="line">	</span><br><span class="line">	/**</span><br><span class="line">	 * 判断某个路径是否存在</span><br><span class="line">	 * @param path 路径</span><br><span class="line">	 * @return 返回状态</span><br><span class="line">	 * @throws KeeperException ZooKeeper异常</span><br><span class="line">	 * @throws InterruptedException 中断异常</span><br><span class="line">	 */</span><br><span class="line">	public static Stat exists(String path) throws KeeperException, InterruptedException &#123;</span><br><span class="line">		return zooKeeper.exists(path, true);</span><br><span class="line">	&#125;</span><br><span class="line">	</span><br><span class="line">	public static void main(String[] args) &#123;</span><br><span class="line">		// znode路径</span><br><span class="line">		String path = &quot;/MyFirst&quot;;		</span><br><span class="line">		try &#123;</span><br><span class="line">			// 创建连接对象</span><br><span class="line">			conn = new ZooKeeperConnection();</span><br><span class="line">			// 连接， 并返回ZooKeeper</span><br><span class="line">			zooKeeper = conn.connect(&quot;127.0.0.1&quot;);</span><br><span class="line">			// 检测路径是否存在</span><br><span class="line">			Stat stat = exists(path);</span><br><span class="line">			// 判断是否为空</span><br><span class="line">			if (null != stat) &#123;</span><br><span class="line">				// 存在打印其版本信息</span><br><span class="line">				System.out.println(&quot;Node exists and the node version is &quot; + stat.getVersion());</span><br><span class="line">			&#125; else &#123;</span><br><span class="line">				System.out.println(&quot;Node does not exists&quot;);</span><br><span class="line">			&#125;</span><br><span class="line">			// 关闭</span><br><span class="line">			conn.close();</span><br><span class="line">		&#125; catch (Exception e) &#123;</span><br><span class="line">			System.out.println(e.getMessage());</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>III. 测试<br><img src="https://upload-images.jianshu.io/upload_images/3110861-974abd030f644240.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="图11.png"></p>
<p>######6). getData(从特定的znode获取数据)<br>I. 方法原型<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">getData(String path, Watcher watcher, Stat stat)</span><br></pre></td></tr></table></figure></p>
<ul>
<li>path - Znode路径。</li>
<li>watcher - 监视器类型的回调函数。当指定的znode的数据改变时，ZooKeeper集合将通过监视器回调进行通知。这是一次性通知。</li>
<li>stat - 返回znode的元数据。</li>
</ul>
<p>II. 代码<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line"> * 获取数据</span><br><span class="line"> * @author mazaiting</span><br><span class="line"> */</span><br><span class="line">public class ZKGetData &#123;</span><br><span class="line">	/**</span><br><span class="line">	 * 定义静态的ZooKeeper对象</span><br><span class="line">	 */</span><br><span class="line">	private static ZooKeeper zooKeeper;</span><br><span class="line">	/**</span><br><span class="line">	 * 定义静态的ZooKeeper连接对象</span><br><span class="line">	 */</span><br><span class="line">	private static ZooKeeperConnection conn;</span><br><span class="line">	</span><br><span class="line">	/**</span><br><span class="line">	 * 判断某个路径是否存在</span><br><span class="line">	 * @param path 路径</span><br><span class="line">	 * @return 返回状态</span><br><span class="line">	 * @throws KeeperException ZooKeeper异常</span><br><span class="line">	 * @throws InterruptedException 中断异常</span><br><span class="line">	 */</span><br><span class="line">	public static Stat exists(String path) throws KeeperException, InterruptedException &#123;</span><br><span class="line">		return zooKeeper.exists(path, true);</span><br><span class="line">	&#125;</span><br><span class="line">	</span><br><span class="line">	public static void main(String[] args) &#123;</span><br><span class="line">		// 路径</span><br><span class="line">		String path = &quot;/MyFirst&quot;;</span><br><span class="line">		// 用户停止(等待)主线程，直到客户端知道获取到数据</span><br><span class="line">		final CountDownLatch connectedSignal = new CountDownLatch(1);</span><br><span class="line">		try &#123;</span><br><span class="line">			// 创建连接对象</span><br><span class="line">			conn = new ZooKeeperConnection();</span><br><span class="line">			// 连接</span><br><span class="line">			zooKeeper = conn.connect(&quot;127.0.0.1&quot;);</span><br><span class="line">			// 检测是否存此路径</span><br><span class="line">			Stat stat = exists(path);</span><br><span class="line">			// 判断是否存在</span><br><span class="line">			if (null != stat) &#123;</span><br><span class="line">				// 获取字节数组</span><br><span class="line">				byte[] bytes = zooKeeper.getData(path, new Watcher() &#123;</span><br><span class="line">					</span><br><span class="line">					@Override</span><br><span class="line">					public void process(WatchedEvent event) &#123;</span><br><span class="line">						// 检测状态</span><br><span class="line">						if (Event.EventType.None == event.getType()) &#123;</span><br><span class="line">							// 判断状态</span><br><span class="line">							switch (event.getState()) &#123;</span><br><span class="line">							case Expired:</span><br><span class="line">								// 关闭</span><br><span class="line">								connectedSignal.countDown();</span><br><span class="line">								break;</span><br><span class="line"></span><br><span class="line">							default:</span><br><span class="line">								break;</span><br><span class="line">							&#125;</span><br><span class="line">						&#125; else &#123;</span><br><span class="line">							try &#123;</span><br><span class="line">								byte[] bn = zooKeeper.getData(path, false, null);</span><br><span class="line">								// 将字节数组转换为字符创</span><br><span class="line">								String data = new String(bn, &quot;UTF-8&quot;);</span><br><span class="line">								// 打印字符串</span><br><span class="line">								System.out.println(data);</span><br><span class="line">								// 关闭</span><br><span class="line">								connectedSignal.countDown();</span><br><span class="line">							&#125; catch (Exception e) &#123;</span><br><span class="line">								// 打印错误日志</span><br><span class="line">								System.out.println(e.getMessage());</span><br><span class="line">							&#125;</span><br><span class="line">						&#125;</span><br><span class="line">					&#125;</span><br><span class="line">				&#125;, null);</span><br><span class="line">				// 将字节数组转换为字符创</span><br><span class="line">				String data = new String(bytes, &quot;UTF-8&quot;);</span><br><span class="line">				// 打印字符串</span><br><span class="line">				System.out.println(data);</span><br><span class="line">				// 等待</span><br><span class="line">				connectedSignal.await();</span><br><span class="line">			&#125; else &#123;</span><br><span class="line">				// 节点不存在</span><br><span class="line">				System.out.println(&quot;Node does not exists&quot;);</span><br><span class="line">			&#125;</span><br><span class="line">		&#125; catch (Exception e) &#123;</span><br><span class="line">			// 打印错误日志</span><br><span class="line">			System.out.println(e.getMessage());</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>III. 测试<br><img src="https://upload-images.jianshu.io/upload_images/3110861-5bb90ff4d65b8f5e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="图12.png"></p>
<p>######7). setData(在特定的znode中设置数据)<br>I. 方法原型<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">setData(String path, byte[] data, int version)</span><br></pre></td></tr></table></figure></p>
<ul>
<li>path- Znode路径。</li>
<li>data - 要存储在指定znode路径中的数据。</li>
<li>version- znode的当前版本。每当数据更改时，ZooKeeper会更新znode的版本号。<br>II. 代码<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line"> * 设置数据</span><br><span class="line"> * @author mazaiting</span><br><span class="line"> */</span><br><span class="line">public class ZKSetData &#123;</span><br><span class="line"></span><br><span class="line">	/**</span><br><span class="line">	 * 定义静态的ZooKeeper对象</span><br><span class="line">	 */</span><br><span class="line">	private static ZooKeeper zooKeeper;</span><br><span class="line">	/**</span><br><span class="line">	 * 定义静态的ZooKeeper连接对象</span><br><span class="line">	 */</span><br><span class="line">	private static ZooKeeperConnection conn;</span><br><span class="line">	</span><br><span class="line">	/**</span><br><span class="line">	 * 更新数据</span><br><span class="line">	 * @param path 路径</span><br><span class="line">	 * @param data 二进制数据</span><br><span class="line">	 * @throws KeeperException ZooKeeper异常</span><br><span class="line">	 * @throws InterruptedException 中断异常</span><br><span class="line">	 */</span><br><span class="line">	public static void update(String path, byte[] data) throws KeeperException, InterruptedException &#123;</span><br><span class="line">		zooKeeper.setData(path, data, zooKeeper.exists(path, true).getVersion());</span><br><span class="line">	&#125;</span><br><span class="line">	</span><br><span class="line">	public static void main(String[] args) &#123;</span><br><span class="line">		// 路径</span><br><span class="line">		String path = &quot;/MyFirst&quot;;</span><br><span class="line">		// 二进制数据</span><br><span class="line">		byte[] data = &quot;Success&quot;.getBytes();</span><br><span class="line">		try &#123;</span><br><span class="line">			// 创建连接对象</span><br><span class="line">			conn = new ZooKeeperConnection();</span><br><span class="line">			// 连接并获取ZooKeeper</span><br><span class="line">			zooKeeper = conn.connect(&quot;127.0.0.1&quot;);</span><br><span class="line">			// 更新数据</span><br><span class="line">			update(path, data);</span><br><span class="line">		&#125; catch (Exception e) &#123;</span><br><span class="line">			// 打印错误信息</span><br><span class="line">			System.out.println(e.getMessage());</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>III. 测试<br>运行程序后，在命令提示符中使用<code>zkCli.cmd</code>开启一个客户端窗口，连接成功后, 输入get /MyFirst(get 路径名)查看数据<br><img src="https://upload-images.jianshu.io/upload_images/3110861-3252dde7be4ea27d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="图13.png"></p>
<p>######8). getChildren(获取特定znode中的所有子节点)<br>I. 方法原型<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">getChildren(String path, Watcher watcher)</span><br></pre></td></tr></table></figure></p>
<ul>
<li>path - Znode路径。</li>
<li>watcher - 监视器类型的回调函数。当指定的znode被删除或znode下的子节点被创建/删除时，ZooKeeper集合将进行通知。这是一次性通知。<br>II. 代码<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line"> * 获取子节点</span><br><span class="line"> * @author mazaiting</span><br><span class="line"> */</span><br><span class="line">public class ZKGetChildren &#123;</span><br><span class="line"></span><br><span class="line">	/**</span><br><span class="line">	 * 定义静态的ZooKeeper对象</span><br><span class="line">	 */</span><br><span class="line">	private static ZooKeeper zooKeeper;</span><br><span class="line">	/**</span><br><span class="line">	 * 定义静态的ZooKeeper连接对象</span><br><span class="line">	 */</span><br><span class="line">	private static ZooKeeperConnection conn;</span><br><span class="line">	</span><br><span class="line">	/**</span><br><span class="line">	 * 判断某个路径是否存在</span><br><span class="line">	 * @param path 路径</span><br><span class="line">	 * @return 返回状态</span><br><span class="line">	 * @throws KeeperException ZooKeeper异常</span><br><span class="line">	 * @throws InterruptedException 中断异常</span><br><span class="line">	 */</span><br><span class="line">	public static Stat exists(String path) throws KeeperException, InterruptedException &#123;</span><br><span class="line">		return zooKeeper.exists(path, true);</span><br><span class="line">	&#125;</span><br><span class="line">	</span><br><span class="line">	public static void main(String[] args) &#123;</span><br><span class="line">		// 路径</span><br><span class="line">		String path = &quot;/MyFirst&quot;;</span><br><span class="line">		try &#123;</span><br><span class="line">			// 创建连接对象</span><br><span class="line">			conn = new ZooKeeperConnection();</span><br><span class="line">			// 连接，并获取ZooKeeper对象</span><br><span class="line">			zooKeeper = conn.connect(&quot;127.0.0.1&quot;);</span><br><span class="line">			// 判断路径是否存在</span><br><span class="line">			Stat stat = exists(path);</span><br><span class="line">			// 判断是否为空</span><br><span class="line">			if (null != stat) &#123;</span><br><span class="line">				// 获取孩子列表</span><br><span class="line">				List&lt;String&gt; children = zooKeeper.getChildren(path, false);</span><br><span class="line">				// 遍历孩子列表</span><br><span class="line">				for(int i = 0; i &lt; children.size(); i++) &#123;</span><br><span class="line">					// 打印数据</span><br><span class="line">					System.out.println(children.get(i));</span><br><span class="line">				&#125;</span><br><span class="line">			&#125; else &#123;</span><br><span class="line">				// 路径不存在</span><br><span class="line">				System.out.println(&quot;Node does not exists&quot;);</span><br><span class="line">			&#125;</span><br><span class="line">		&#125; catch (Exception e) &#123;</span><br><span class="line">			// 打印错误信息</span><br><span class="line">			System.out.println(e.getMessage());</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>III. 测试</p>
<ul>
<li><p>先在命令提示符窗口中添加两个孩子节点<br><img src="https://upload-images.jianshu.io/upload_images/3110861-d4d3d1124c15214a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="图14.png"></p>
</li>
<li><p>运行项目<br><img src="https://upload-images.jianshu.io/upload_images/3110861-7e5f30375b57a7f0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="图15.png"></p>
</li>
</ul>
<p>######9). delete(删除特定的znode及其所有子项)<br>I. 方法原型<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">delete(String path, int version)</span><br></pre></td></tr></table></figure></p>
<ul>
<li>path - Znode路径。</li>
<li>version - znode的当前版本。<br>II. 代码<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line"> * 删除路径</span><br><span class="line"> * @author mazaiting</span><br><span class="line"> */</span><br><span class="line">public class ZKDelete &#123;</span><br><span class="line"></span><br><span class="line">	/**</span><br><span class="line">	 * 定义静态的ZooKeeper对象</span><br><span class="line">	 */</span><br><span class="line">	private static ZooKeeper zooKeeper;</span><br><span class="line">	/**</span><br><span class="line">	 * 定义静态的ZooKeeper连接对象</span><br><span class="line">	 */</span><br><span class="line">	private static ZooKeeperConnection conn;</span><br><span class="line">	</span><br><span class="line">	/**</span><br><span class="line">	 * 删除节点</span><br><span class="line">	 * @param path 路径</span><br><span class="line">	 * @throws InterruptedException 中断异常</span><br><span class="line">	 * @throws KeeperException ZooKeeper异常</span><br><span class="line">	 */</span><br><span class="line">	public static void delete(String path) throws InterruptedException, KeeperException &#123;</span><br><span class="line">		zooKeeper.delete(path, zooKeeper.exists(path, true).getVersion());</span><br><span class="line">	&#125;</span><br><span class="line">	</span><br><span class="line">	public static void main(String[] args) &#123;</span><br><span class="line">		// 路径</span><br><span class="line">		String path = &quot;/MyFirst/first&quot;;</span><br><span class="line">		try &#123;</span><br><span class="line">			// 创建ZooKeeper连接</span><br><span class="line">			conn = new ZooKeeperConnection();</span><br><span class="line">			// 连接</span><br><span class="line">			zooKeeper = conn.connect(&quot;127.0.0.1&quot;);</span><br><span class="line">			// 删除</span><br><span class="line">			delete(path);</span><br><span class="line">		&#125; catch (Exception e) &#123;</span><br><span class="line">			// 打印错误信息</span><br><span class="line">			System.out.println(e.getMessage());</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ul>
<p>III. 测试<br>删除前/MyFirst的numChildren量比删除后多1<br><img src="https://upload-images.jianshu.io/upload_images/3110861-1fc478e32ca8db9f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="图16.png"></p>
<p>####<a href="https://gitee.com/mazaiting/distributed" target="_blank" rel="noopener">代码下载</a></p>

      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      
      
      

      
        <div class="post-nav">
          <div class="post-nav-next post-nav-item">
            
              <a href="/blog/2018/08/06/Distributed/分布式--Spring-Cloud/" rel="next" title="分布式--Spring-Cloud">
                <i class="fa fa-chevron-left"></i> 分布式--Spring-Cloud
              </a>
            
          </div>

          <span class="post-nav-divider"></span>

          <div class="post-nav-prev post-nav-item">
            
              <a href="/blog/2018/08/06/Distributed/分布式系统学习系列/" rel="prev" title="分布式系统学习系列">
                分布式系统学习系列 <i class="fa fa-chevron-right"></i>
              </a>
            
          </div>
        </div>
      

      
      
    </footer>
  </div>
  
  
  
  </article>



    <div class="post-spread">
      
    </div>
  </div>


          </div>
          


          

  



        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    
    <div class="sidebar-inner">

      

      

      <section class="site-overview-wrap sidebar-panel sidebar-panel-active">
        <div class="site-overview">
          <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
            
              <img class="site-author-image" itemprop="image"
                src="/blog/images/avatar.jpeg"
                alt="凌浩雨" />
            
              <p class="site-author-name" itemprop="name">凌浩雨</p>
              <p class="site-description motion-element" itemprop="description">专业从事于移动端开发，Android与iOS均有涉及，主做Android开发与React Native开发</p>
          </div>

          <nav class="site-state motion-element">

            
              <div class="site-state-item site-state-posts">
              
                <a href="/blog/archives/">
              
                  <span class="site-state-item-count">393</span>
                  <span class="site-state-item-name">posts</span>
                </a>
              </div>
            

            

            

          </nav>

          

          

          
          

          
          

          

        </div>
      </section>

      

      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright">&copy; <span itemprop="copyrightYear">2018</span>
  <span class="with-love">
    <i class="fa fa-user"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">凌浩雨</span>

  
</div>


  <div class="powered-by">Powered by <a class="theme-link" target="_blank" href="https://hexo.io">Hexo</a></div>



  <span class="post-meta-divider">|</span>



  <div class="theme-info">Theme &mdash; <a class="theme-link" target="_blank" href="https://github.com/iissnan/hexo-theme-next">NexT.Pisces</a> v5.1.4</div>




        







        
      </div>
    </footer>

    
      <div class="back-to-top">
        <i class="fa fa-arrow-up"></i>
        
      </div>
    

    

  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>









  












  
  
    <script type="text/javascript" src="/blog/lib/jquery/index.js?v=2.1.3"></script>
  

  
  
    <script type="text/javascript" src="/blog/lib/fastclick/lib/fastclick.min.js?v=1.0.6"></script>
  

  
  
    <script type="text/javascript" src="/blog/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>
  

  
  
    <script type="text/javascript" src="/blog/lib/velocity/velocity.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/blog/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/blog/lib/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>
  


  


  <script type="text/javascript" src="/blog/js/src/utils.js?v=5.1.4"></script>

  <script type="text/javascript" src="/blog/js/src/motion.js?v=5.1.4"></script>



  
  


  <script type="text/javascript" src="/blog/js/src/affix.js?v=5.1.4"></script>

  <script type="text/javascript" src="/blog/js/src/schemes/pisces.js?v=5.1.4"></script>



  
  <script type="text/javascript" src="/blog/js/src/scrollspy.js?v=5.1.4"></script>
<script type="text/javascript" src="/blog/js/src/post-details.js?v=5.1.4"></script>



  


  <script type="text/javascript" src="/blog/js/src/bootstrap.js?v=5.1.4"></script>



  


  




	





  





  












  





  

  

  

  
  

  

  

  

</body>
</html>
